/**
 * ESUI (Enterprise Simple UI)
 * Copyright 2015 Baidu Inc. All rights reserved.
 *
 * @ignore
 * @file 二级checkbox
 * @author hongfeng(homfen@outlook.com)
 */

define(
    function (require) {
        var u = require('underscore');
        var lib = require('esui/lib');
        var eoo = require('eoo');
        var InputControl = require('esui/InputControl');
        var painters = require('esui/painters');
        var esui = require('esui');
        require('esui/CheckBox');

        var CheckboxGroup = eoo.create(
            InputControl,
            {

                /**
                 * 控件类型，始终为 `CheckboxGroup`
                 *
                 * @type {string}
                 * @readonly
                 * @override
                 */
                type: 'CheckboxGroup',

                /**
                 * 初始化参数
                 *
                 * @param {Object} [options] 构造函数传入的参数
                 * @protected
                 * @override
                 */
                initOptions: function (options) {
                    var properties = {
                        datasource: [],
                        value: [],
                        maxSelected: 0
                    };

                    u.extend(properties, options);
                    this.setProperties(properties);
                },

                /**
                 * 初始化DOM结构
                 *
                 * @method
                 * @protected
                 * @override
                 */
                initStructure: function () {
                    var boxes = createBoxes.call(this);
                    var body = create.call(this, 'body', 'div', boxes);

                    this.main.innerHTML = body;
                    this.initChildren();
                    var inputs = this.main.getElementsByTagName('input');
                    inputs = Array.prototype.slice.call(inputs);
                    inputs.forEach(function (input) {
                        var parentInput = input.parentNode;
                        var parentValue = parentInput.getAttribute('data-ui-parent-value');
                        if (parentValue) {
                            input.setAttribute('name', parentValue);
                        }
                    });
                },

                /**
                 * 初始化事件
                 *
                 * @method
                 * @protected
                 * @override
                 */
                initEvents: function () {
                    var inputs = this.main.getElementsByTagName('input');
                    u.each(inputs, function (input) {
                        if (input.disabled) {
                            return;
                        }

                        this.helper.addDOMEvent(input, 'click', u.bind(
                            function (e) {
                                var target = e.target;

                                // 父级
                                if (!target.name) {
                                    checkSub(inputs, target.value, target.checked, target);
                                }
                                // 子级
                                else {
                                    checkSuper(inputs, target.name, target.checked);
                                }

                                this.fire('change');
                            }, this)
                        );
                    }, this);
                },

                /**
                 * 获取选中的checkbox值
                 *
                 * @override
                 * @return {Array}
                 */
                getValue: function () {
                    var inputs = this.main.getElementsByTagName('input');
                    var subs = u.filter(inputs, function (input) {
                        return !!input.name;
                    });

                    return u.reduce(subs, function (result, input) {
                        input.checked && result.push(input.value);
                        return result;
                    }, []);
                },

                /**
                 * 获取选中的checkbox值
                 *
                 * @override
                 * @return {Array}
                 */
                getRawValue: function () {
                    return this.getValue();
                },

                /**
                 * 根据传入的值勾选checkbox
                 *
                 * @override
                 */
                setValue: function (value) {
                    var inputs = this.main.getElementsByTagName('input');
                    var subs = u.filter(inputs, function (input) {
                        return !!input.name;
                    });

                    u.each(subs, function (input) {
                        if (u.indexOf(value, input.value) !== -1) {
                            input.checked = true;
                        }
                        else {
                            input.checked = false;
                        }

                        var name = input.name;
                        checkSuper(inputs, name, input.checked);
                    });

                    this.fire('change');
                },

                /**
                 * 返回checkbox总数和勾选数，供外部使用
                 *
                 * @return {Object}
                 */
                returnCount: function () {
                    var inputs = this.main.getElementsByTagName('input');
                    if (inputs.length) {
                        var all = u.groupBy(inputs, function (input) {
                            return input.name ? 'sub' : 'super';
                        });

                        var subCount = all.sub.length;
                        var subSelected = u.reduce(all.sub, function (num, item) {
                            return num + (item.checked ? 1 : 0);
                        }, 0);
                        return {subCount: subCount, subSelected: subSelected};
                    }
                    return {subCount: 0, subSelected: 0};
                },

                /**
                 * 重渲染
                 *
                 * @method
                 * @protected
                 * @override
                 */
                repaint: painters.createRepaint(
                    InputControl.prototype.repaint,
                    {
                        name: 'rawValue',
                        paint: function (checkboxGroup, value) {
                            checkboxGroup.setValue(value);
                        }
                    }
                )
            }
        );

        /**
         * 生成DOM节点
         *
         * @param {string} [part] part名称
         * @param {string} [nodeName] 元素类型
         * @param {string} [innerHTML] 内部HTML
         * @return {string} 返回整个HTML
         */
        function create(part, nodeName, innerHTML) {
            return this.helper.getPartBeginTag(part, nodeName)
                + innerHTML
                + this.helper.getPartEndTag(part, nodeName);
        }

        /**
         * 生成所有checkbox
         *
         * @return {string} html
         */
        function createBoxes() {
            var html = '';
            var all = u.clone(this.datasource);
            u.each(all, function (fields, dimension) {

                // 这个维度下没有自定义列
                if (!fields.children.length) {
                    return;
                }

                var superValue = fields.value;
                var legend = lib.format(
                    '<input type="checkbox" title="${title}" data-ui-variants="custom" '
                        + 'data-ui-type="CheckBox" data-ui-title="${title}" '
                        + 'id="${id}" data-ui-value="${value}"'
                        + (fields.disabled
                           ? ' data-ui-disabled="disabled">'
                           : '>'),
                    {
                        title: fields.text,
                        value: superValue,
                        id: this.helper.getId(dimension + '-super')
                    }
                );

                var head = create.call(this, 'dimension-head-' + dimension, 'div', legend);

                var boxes = [];
                u.each(fields.children, function (item, index) {
                    var tpl = '<input data-ui-variants="custom" type="checkbox" '
                        + 'data-ui-type="CheckBox" data-ui-value="${value}" '
                        + 'title="${title}" data-ui-title="${title}" id="${id}" data-ui-parent-value="${name}"'
                        + (item.disabled
                           ? ' data-ui-disabled="disabled">'
                           : '>');

                    var box = lib.format(
                        tpl,
                        {
                            title: item.text,
                            value: item.value,
                            id: this.helper.getId(dimension + '-' + item.value),
                            name: superValue
                        }
                    );
                    boxes.push(box);
                }, this);

                var group = create.call(this, 'dimension-group', 'p', boxes.join('\n'));

                html += create.call(this, 'dimension-' + dimension, 'section', head + group);
            }, this);

            return html;
        }

        /**
         * 根据上级checkbox检查下级checkbox
         *
         * @param {Array} [inputs] 所有的inputs
         * @param {string} [groupName] 要检查的inputs的group
         * @param {boolean} [checked] 选中状态
         * @param {Object} [parent] 父级元素
         */
        function checkSub(inputs, groupName, checked, parent) {
            var subInputs = u.filter(inputs, function (input) {
                return input.name === groupName;
            });

            var allChecked = true;
            var someChecked = false;
            u.each(subInputs, function (input) {
                !input.disabled && (input.checked = checked);
                if (input.checked) {
                    someChecked = true;
                }
                else {
                    allChecked = false;
                }
            });
            if (allChecked) {
                parent.indeterminate = false;
            }
            else if (someChecked) {
                parent.indeterminate = true;
            }
            else {
                parent.indeterminate = false;
            }
        }

        /**
         * 根据下级所有checkbox检查上级checkbox
         *
         * @param {Array} [inputs] 所有的inputs
         * @param {string} [groupName] 要检查的inputs的group
         * @param {boolean} [checked] 选中状态
         */
        function checkSuper(inputs, groupName, checked) {
            var superInput = u.find(inputs, function (input) {
                return input.value === groupName;
            });

            var otherSiblings = u.filter(inputs, function (input) {
                return input.name === groupName;
            });

            var allChecked = true;
            var someChecked = false;
            u.each(otherSiblings, function (input) {
                if (input.checked) {
                    someChecked = true;
                }
                else {
                    allChecked = false;
                }
            });
            allChecked = checked && allChecked;

            if (allChecked) {
                superInput.checked = true;
                superInput.indeterminate = false;
            }
            else if (someChecked) {
                superInput.checked = false;
                superInput.indeterminate = true;
            }
            else {
                superInput.checked = false;
                superInput.indeterminate = false;
            }
        }

        esui.register(CheckboxGroup);
        return CheckboxGroup;
    }
);
